package basis.log;

import java.io.IOException;
import java.util.LinkedList;
import javax.swing.JOptionPane;

import basis.ea.EA;


/**
 * Die Klasse Logbuch bietet die Moeglichkeit Informationen und 
 * Fehlermeldungen zentral und chronologisch zu verwalten.
 * 
 * Datei: Logbuch.java                   
 * Datum: 06.11.2011   
 *                  
 * @author Alexander Bredo 
 * @version 0.4
 */
public class Logbuch
{
  private String klassenbezeichnung;
  private boolean still;
  private static LinkedList<Logelement> fehlerListe = 
      new LinkedList<Logelement> ();


  /**
   * Erstellt ein Logbuch-Objekt
   * @param klassenbezeichnung fuer inviduelle Speicherorte
   * @param still gibt an, ob eine Fehlermeldung angezeigt wird.
   */
  public Logbuch (String klassenbezeichnung, boolean still) 
      throws IllegalArgumentException
  {
    if (klassenbezeichnung.isEmpty ())
    {
      throw new IllegalArgumentException (
          "Leere Klassennamen sind nicht erlaubt.");
    }

    this.klassenbezeichnung = klassenbezeichnung;
    this.still = still;
    einlesen ();
  }


  /** 
   * Speichert eine Fehlermeldung und gibt sie ggf. aus
   */
  public void fehler (String text)
  {
    Logelement le = new Logelement (text, klassenbezeichnung,
        Meldungstypen.Fehler);
    fehlerListe.add (le);

    if (!still)
    {
      JOptionPane.showMessageDialog (null, le.toString (), "Fehler",
          JOptionPane.ERROR_MESSAGE);
    }

    speichern ();
  }


  /** 
   * Speichert eine Warnmeldung und gibt sie ggf. aus
   */
  public void warnung (String text)
  {
    Logelement le = new Logelement (text, klassenbezeichnung,
        Meldungstypen.Warnung);
    fehlerListe.add (le);

    if (!still)
    {
      JOptionPane.showMessageDialog (null, le.toString (), "Warnung",
          JOptionPane.WARNING_MESSAGE);
    }

    speichern ();
  }


  /** 
   * Speichert eine Informationsmeldung und gibt sie ggf. aus
   */
  public void information (String text)
  {
    Logelement le = new Logelement (text, klassenbezeichnung,
        Meldungstypen.Information);
    fehlerListe.add (le);

    if (!still)
    {
      JOptionPane.showMessageDialog (null, le.toString (),
          "Information", JOptionPane.INFORMATION_MESSAGE);
    }

    speichern ();
  }


  /** 
   * Gibt die letzte Meldung nochmals zurueck
   */
  public static String gibLetzteMeldung ()
  {
    Logelement le = fehlerListe.getLast ();
    return le.toString ();
  }


  /** 
   * Speichert die Fehlerliste des Objektes
   */
  private void speichern ()
  {
    EA ea = new EA (gibDateiname ());
    try
    {
      ea.speichern (fehlerListe);
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }


  /** 
   * Liest die Fehlerliste des Objektes ein
   */
  private void einlesen ()
  {
    EA ea = new EA (gibDateiname ());
    Object objekt;
    
    if (ea.istGespeichertesObjektVorhanden ())
    {
      try
      {
        objekt = ea.einlesen ();
        if (objekt instanceof LinkedList<?>)
        {
          /* 
           * Die nachfolgende Warnung ist darin begruendet, dass 
           * generische Datentypen zur Laufzeit nicht zur Verfuegung 
           * stehen. Das heisst sie werden vom Compiler entfernt und 
           * koennen zur Laufzeit bei der Typumwandlung nicht 
           * ueberprueft werden. 
           */
          fehlerListe = (LinkedList<Logelement>) objekt;
        }
        else
        {
          /* Darf im Normalfall nicht auftreten (ausser falsche Datei)  */
          fehlerListe = new LinkedList<Logelement> ();
        }
      }
      catch (ClassNotFoundException e)
      {
        e.printStackTrace();
      }
      catch (IOException e)
      {
        e.printStackTrace();
      }
    }
    else
    {
      fehlerListe = new LinkedList<Logelement> ();
    }
  }


  /** 
   * Gibt den Dateinamen fuer das aktuelle Objekt zurueck
   */
  private String gibDateiname ()
  {
    String bezeichnung = getClass ().getName ();
    return bezeichnung + "." + klassenbezeichnung;
  }
}
